// Fill out your copyright notice in the Description page of Project Settings.


#include "SOneList.h"
#include "SlateOptMacros.h"
#include "ListLibrary/GlobalConfig.h"
#include "ListLibrary/BaseWidget/SCollisionScrollBox_List.h"
#include "ListLibrary/BaseWidget/STextBlock_TextStyleLambda_List.h"
#include "Widgets/Colors/SColorBlock.h"
#include "Widgets/Images/SImage.h"
#include "Widgets/Input/SSlider.h"
#include "Widgets/Layout/SConstraintCanvas.h"
#include "Widgets/Layout/SSpacer.h"
#include "Widgets/Notifications/SProgressBar.h"
#include "Widgets/Text/SMultiLineEditableText.h"

BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION

SOneList::SOneList():BeforeWidth(9999),ShowYuan(false)
{
}

void SOneList::Construct(const FArguments& InArgs)
{
	ChildSlot
	[
		SNew(SVerticalBox)
		+ SVerticalBox::Slot().AutoHeight()
		[
			SAssignNew(TitleText, STextBlock_TextStyleLambda_List)
			.Justification(ETextJustify::Left)
			.Text(FText::FromString(InArgs._Title))
			.TEXTSTYLE(InArgs._TitleStrStyle)
		]
		+ SVerticalBox::Slot().FillHeight(1).Padding(FMargin(0, 16, 0, 0))
		[
			SAssignNew(ListContent, SBox)
		]
	];
	UpDataList(1000, TMap<FString, float>());
}

END_SLATE_FUNCTION_BUILD_OPTIMIZATION

void SOneList::UpDataList(int width, TMap<FString, float> ListData)
{
	BeforeWidth = width;
	YuanImageS.Empty();
	//先计算所需要的宽度保底每个柱子站36宽度像素
	int MinWidth = 50 + ListData.Num() * 36;
	if (MinWidth < width)
	{
		AutoWidthList(ListData);
	}
	else
	{
		FixedWidthList(ListData);
	}
}

int32 SOneList::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
{
	if (YuanImageS.Num() > 0 && ShowYuan)
	{
		FGeometry ZeroGeometry = YuanImageS[0]->GetCachedGeometry();
		//AbsolutePosition代表再父类中的位置
		if (!(ZeroGeometry.AbsolutePosition.X == 0 && ZeroGeometry.AbsolutePosition.Y == 0))
		{
			FGeometry OneListGeometry = GetCachedGeometry(); //获取自己再软件中的位置
			TArray<FVector2D> Points;
			for (int i = 0; i < YuanImageS.Num(); i++)
			{
				FGeometry TempGeometry = YuanImageS[i]->GetCachedGeometry(); //获取圆球再软件中的位置
				float X = (TempGeometry.AbsolutePosition.X - OneListGeometry.AbsolutePosition.X + 10) / AllottedGeometry.Scale;
				float Y = (TempGeometry.AbsolutePosition.Y - OneListGeometry.AbsolutePosition.Y + 10) / AllottedGeometry.Scale;
				FVector2D position = FVector2D(X,Y); //算出圆球在控件中的位置
				Points.Add(position);
			}
			FSlateDrawElement::MakeLines( //绘制线条
				OutDrawElements,
				LayerId++,
				AllottedGeometry.ToPaintGeometry(),
				Points, //线条坐标
				bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect, //在原色基础之上在增加别的效果
				FColor::White, //显得颜色
				true, //抗锯齿
				AllottedGeometry.Scale //线的宽度
			);
		}
	}
	return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
}

void SOneList::AutoWidthList(TMap<FString, float> ListData)
{
	//首先计算出要分成几个范围
	//范围定在6-10之间并自动调整
	//先得到当前表的最大值
	int MaxValue = 100;
	//两条数据之间的增长值
	int GrowValue = 20;
	
	bool first = true;
	for (auto& item : ListData)
	{
		if(first)
		{
			MaxValue = item.Value;
			first = false;
		}
		if (item.Value > MaxValue)
			MaxValue = item.Value;
	}

	if(MaxValue <= 5)
	{
		MaxValue = 5;
		GrowValue = 1;
	}
	else if(MaxValue <= 10)
	{
		MaxValue = 10;
		GrowValue = 2;
	}
	else if(MaxValue <= 50)
	{
		MaxValue = 50;
		GrowValue = 10;
	}
	else if (MaxValue <= 100)
	{
		MaxValue = 100;
		GrowValue = 20;
	}
	else if (MaxValue <= 500)
	{
		MaxValue = 500;
		GrowValue = 100;
	}
	else if (MaxValue <= 1000)
	{
		MaxValue = 1000;
		GrowValue = 200;
	}
	else if (MaxValue <= 5000)
	{
		MaxValue = 5000;
		GrowValue = 1000;
	}
	else if (MaxValue <= 10000)
	{
		MaxValue = 10000;
		GrowValue = 2000;
	}
	else
	{
		GrowValue = MaxValue / 5;
	}
	//再开始绘制表格

	int MaxLen = FString::FromInt(MaxValue).Len(); //最大字符长度
	//这里的代码主要是绘制左侧的数字和后面的横线
	TSharedPtr<SVerticalBox> DrawLine = SNew(SVerticalBox);
	for (int item = MaxValue; item >= GrowValue; item -= GrowValue)
	{
		FString ValueStr = FString::FromInt(item);

		if (ValueStr.Len() < MaxLen)
		{
			int AddSpace = MaxLen - ValueStr.Len();
			FString Space = "";
			for (int i = 0; i < AddSpace; i++)
			{
				Space.Append("  ");
			}
			ValueStr = Space + ValueStr;
		}
		DrawLine->AddSlot().FillHeight(1)
		[
			SNew(SHorizontalBox)
			+ SHorizontalBox::Slot().AutoWidth().Padding(FMargin(0, -10, 0, 0))
			[
				SNew(STextBlock_TextStyleLambda_List)
             			.Justification(ETextJustify::Right)
             			.Text(FText::FromString(ValueStr))
             			.TEXTSTYLE("AlibabaRegular_12_83AAD6FF")
			]
			+ SHorizontalBox::Slot()
			  .Padding(FMargin(12, 0, 0, 0))
			  .FillWidth(1)
			[
				SNew(SVerticalBox)
				+ SVerticalBox::Slot().AutoHeight()
				[
					SNew(SBox).HeightOverride(1)
					[
						SNew(SImage).SETIMAGE("XuXian")
					]
				]
				+ SVerticalBox::Slot().FillHeight(1)
				[
					SNew(SSpacer)
				]
			]
		];
	}


	//用于显示图表中背景的线和柱子
	TSharedPtr<SOverlay> List_SOverlay = SNew(SOverlay);
	//用于显示柱子
	TSharedPtr<SHorizontalBox> Pillar = SNew(SHorizontalBox);
	//用于显示柱子对应的名字
	TSharedPtr<SHorizontalBox> NameLise = SNew(SHorizontalBox);


	TSharedPtr<SImage> haha;
	for (auto& item : ListData)
	{
		NameLise->AddSlot().FillWidth(1)
		[

		SNew(SMultiLineEditableText).Justification(ETextJustify::Center)
			.TextStyle(ListUIStyle::GetTextBlockStyle("AlibabaRegular_10_83AAD6FF"))
				 .IsReadOnly(true) //只读属性
				 .AutoWrapText(true)
				 .ToolTipText(FText::FromString(item.Key))
				 .Text(FText::FromString(item.Key))
		];

		TSharedPtr<SImage> TempYuan;
		Pillar->AddSlot().FillWidth(1).Padding(FMargin(7, 0))
		[
			SNew(SOverlay)
			+ SOverlay::Slot()
			[
				SNew(SColorBlock).Color(FLinearColor(0.27, 0.4, 0.7, 0.1))
			]
			+ SOverlay::Slot().Padding(FMargin())
			[
				SNew(SHorizontalBox)
				+ SHorizontalBox::Slot().FillWidth(1)
				[
					SNew(SSpacer)
				]
				+ SHorizontalBox::Slot().FillWidth(2)
				[

					SNew(SVerticalBox)
					+ SVerticalBox::Slot().FillHeight(MaxValue - item.Value)
					[
						SNew(SSpacer)
					]
					+ SVerticalBox::Slot().FillHeight(item.Value)
					[
						SNew(SOverlay)
						+ SOverlay::Slot()
						[
							SNew(SImage)
                     		.SETIMAGE("ZhuZiBlue")
                     		.ToolTipText(FText::FromString(FString::FromInt(item.Value)))
						]
						+ SOverlay::Slot()
						  .HAlign(HAlign_Center)
						  .VAlign(VAlign_Top)
						  .Padding(FMargin(0, -20, 0, 0))
						[
							SNew(SVerticalBox)
							.Visibility_Lambda([this]()
							{
								if(ShowYuan)
									return EVisibility::Visible;
								else
								{
									return EVisibility::Collapsed;
								}
							})
							+SVerticalBox::Slot().AutoHeight()
							[
								SNew(STextBlock_TextStyleLambda_List)
					 			.Justification(ETextJustify::Right)
					 			.Text(FText::FromString(FString::FromInt(item.Value)))
					 			.TEXTSTYLE("AlibabaRegular_12_FFFFFFFF")
							]
							+SVerticalBox::Slot().AutoHeight().Padding(FMargin(0,-12,0,0))
							[
								SAssignNew(TempYuan, SImage)
								.SETIMAGE("Yuan")
							]
						]
					]
				]
				+ SHorizontalBox::Slot().FillWidth(1)
				[
					SNew(SSpacer)
				]
			]
		];
		YuanImageS.Add(TempYuan);
	}

	FString TempStr = "";
	FString ZeroStr = "";
	for (int i = 0; i < MaxLen; i++)
		TempStr.Append("  ");
	ZeroStr = TempStr.Left(TempStr.Len() - 2);
	ZeroStr.Append("0");
	List_SOverlay->AddSlot()
	[
		DrawLine.ToSharedRef()
	];
	List_SOverlay->AddSlot()[
		SNew(SHorizontalBox)
		+ SHorizontalBox::Slot().AutoWidth()
		[
			SNew(STextBlock_TextStyleLambda_List)
				 .Justification(ETextJustify::Right)
				 .Text(FText::FromString(TempStr))
				 .TEXTSTYLE("AlibabaRegular_12_83AAD6FF")
		]
		+ SHorizontalBox::Slot().FillWidth(1).Padding(FMargin(12, 0, 0, 0))
		[
			Pillar.ToSharedRef()
		]

	];

	//显示整个表格
	TSharedPtr<SVerticalBox> ShowList;
	SAssignNew(ShowList, SVerticalBox)
		+ SVerticalBox::Slot().FillHeight(1)
		[
			List_SOverlay.ToSharedRef()
		]
		+ SVerticalBox::Slot().AutoHeight()
		[
			SNew(SBox).HeightOverride(1)
			[
				SNew(SHorizontalBox)
				+ SHorizontalBox::Slot().AutoWidth()
				[
					SNew(STextBlock_TextStyleLambda_List)
					 .Justification(ETextJustify::Right)
					 .Text(FText::FromString(TempStr))
					 .TEXTSTYLE("AlibabaRegular_12_83AAD6FF")
				]
				+ SHorizontalBox::Slot().FillWidth(1).Padding(FMargin(12, 0, 0, 0))
				[
					SNew(SColorBlock).Color(FLinearColor(0.27, 0.4, 0.67, 1.0))
				]
			]
		]
		+ SVerticalBox::Slot().AutoHeight()
		[
			SNew(SHorizontalBox)
			+ SHorizontalBox::Slot().AutoWidth().Padding(FMargin(0, -10, 0, 0))
			[
				SNew(STextBlock_TextStyleLambda_List)
						 .Justification(ETextJustify::Right)
						 .Text(FText::FromString(ZeroStr))
						 .TEXTSTYLE("AlibabaRegular_12_83AAD6FF")
			]
			+ SHorizontalBox::Slot().FillWidth(1).Padding(FMargin(12, 0, 0, 0))
			[
				NameLise.ToSharedRef()
			]
		];
	ListContent->SetContent(ShowList.ToSharedRef());
}

void SOneList::FixedWidthList(TMap<FString, float> ListData)
{
	//首先计算出要分成几个范围
	//范围定在6-10之间并自动调整
	//先得到当前表的最大值
	int MaxValue = 100;
	//两条数据之间的增长值
	int GrowValue = 20;

	bool first = true;
	for (auto& item : ListData)
	{
		if(first)
		{
			MaxValue = item.Value;
			first = false;
		}
		if (item.Value > MaxValue)
			MaxValue = item.Value;
	}

	if(MaxValue <= 5)
	{
		MaxValue = 5;
		GrowValue = 1;
	}
	else if(MaxValue <= 10)
	{
		MaxValue = 10;
		GrowValue = 2;
	}
	else if(MaxValue <= 50)
	{
		MaxValue = 50;
		GrowValue = 10;
	}
	else if (MaxValue <= 100)
	{
		MaxValue = 100;
		GrowValue = 20;
	}
	else if (MaxValue <= 500)
	{
		MaxValue = 500;
		GrowValue = 100;
	}
	else if (MaxValue <= 1000)
	{
		MaxValue = 1000;
		GrowValue = 200;
	}
	else if (MaxValue <= 5000)
	{
		MaxValue = 5000;
		GrowValue = 1000;
	}
	else if (MaxValue <= 10000)
	{
		MaxValue = 10000;
		GrowValue = 2000;
	}
	else
	{
		GrowValue = MaxValue / 5;
	}
	//再开始绘制表格

	int MaxLen = FString::FromInt(MaxValue).Len(); //最大字符长度
	//这里的代码主要是绘制左侧的数字和后面的横线
	TSharedPtr<SVerticalBox> DrawLine = SNew(SVerticalBox);
	for (int item = MaxValue; item >= GrowValue; item -= GrowValue)
	{
		FString ValueStr = FString::FromInt(item);

		if (ValueStr.Len() < MaxLen)
		{
			int AddSpace = MaxLen - ValueStr.Len();
			FString Space = "";
			for (int i = 0; i < AddSpace; i++)
			{
				Space.Append("  ");
			}
			ValueStr = Space + ValueStr;
		}
		DrawLine->AddSlot().FillHeight(1)
		[
			SNew(SHorizontalBox)
			+ SHorizontalBox::Slot().AutoWidth().Padding(FMargin(0, -10, 0, 0))
			[
				SNew(STextBlock_TextStyleLambda_List)
             			.Justification(ETextJustify::Right)
             			.Text(FText::FromString(ValueStr))
             			.TEXTSTYLE("AlibabaRegular_12_83AAD6FF")
			]
			+ SHorizontalBox::Slot()
			  .Padding(FMargin(12, 0, 0, 0))
			  .FillWidth(1)
			[
				SNew(SVerticalBox)
				+ SVerticalBox::Slot().AutoHeight()
				[
					SNew(SBox).HeightOverride(1)
					[
						SNew(SImage).SETIMAGE("XuXian")
					]
				]
				+ SVerticalBox::Slot().FillHeight(1)
				[
					SNew(SSpacer)
				]
			]
		];
	}


	//用于显示图表中背景的线和柱子
	TSharedPtr<SOverlay> List_SOverlay = SNew(SOverlay);
	//用于显示柱子
	TSharedPtr<SHorizontalBox> Pillar = SNew(SHorizontalBox);
	//用于显示柱子对应的名字
	TSharedPtr<SConstraintCanvas> NameLise = SNew(SConstraintCanvas);


	int itemi = 0;
	for (auto& item : ListData)
	{
		NameLise->AddSlot().Offset(FMargin(itemi * 36, 50, 216, 150))
		[
			SNew(SButton)
             	.ButtonStyle(ListUIStyle::GetButtonStyle("transparencyStyle"))
             	.VAlign(VAlign_Top)
             	.ToolTipText(FText::FromString(item.Key))
             	.HAlign(HAlign_Left)
             	.RenderTransform(FSlateRenderTransform(Concatenate(FVector2D(100.0f, -75.0f), FQuat2D(PI / 4.0f))))
			[
				SNew(STextBlock_TextStyleLambda_List)
							 .Justification(ETextJustify::Right)
							 .Text(FText::FromString(item.Key))
							 .TEXTSTYLE("AlibabaRegular_12_83AAD6FF")

			]
		];
		itemi++;

		TSharedPtr<SImage> TempYuan;
		Pillar->AddSlot().AutoWidth().Padding(FMargin(6, 0))
		[
			SNew(SBox).WidthOverride(24)
			[
				SNew(SOverlay)
				+ SOverlay::Slot() //柱状图的背景
				[
					SNew(SColorBlock).Color(FLinearColor(0.27, 0.4, 0.7, 0.1))
				]
				+ SOverlay::Slot()
				[
					SNew(SHorizontalBox)
					+ SHorizontalBox::Slot().FillWidth(1)
					[
						SNew(SBox)
						[
							SNew(SSpacer)
						]
					]
					+ SHorizontalBox::Slot().FillWidth(2)
					[
						SNew(SBox)
						[
							SNew(SVerticalBox)
							+ SVerticalBox::Slot().FillHeight(MaxValue - item.Value)
							[
								SNew(SSpacer)
							]
							+ SVerticalBox::Slot().FillHeight(item.Value)
							[
								SNew(SImage)
						 		.SETIMAGE("ZhuZiBlue")
						 		.ToolTipText(FText::FromString(FString::FromInt(item.Value)))
							]
						]

					]
					+ SHorizontalBox::Slot().FillWidth(1)
					[
						SNew(SBox)
						[
							SNew(SSpacer)
						]
					]
				]
			]
		];

		//YuanImageS.Add(TempYuan);
	}


	//增加了5个空的柱状图,意图是名字倾斜后会占用右边的空间,如果不加两条空数据则后面没有空间显示倾斜的名字
	for (int i = 0; i < 5; i++)
	{
		/*NameLise->AddSlot().AutoWidth()
		[
			SNew(SBox).WidthOverride(36)
			[

				SNew(SButton)
					.ButtonStyle(ListUIStyle::GetButtonStyle("transparencyStyle"))
					.VAlign(VAlign_Fill)
					.HAlign(HAlign_Fill)
				[
					SNew(SSpacer)
				]
			]
		];*/
		Pillar->AddSlot().AutoWidth().Padding(FMargin(6, 0))
		[
			SNew(SBox).WidthOverride(24)
			[
				SNew(SSpacer)
			]
		];
	}


	FString TempStr = "";
	FString ZeroStr = "";
	for (int i = 0; i < MaxLen; i++)
		TempStr.Append("  ");
	ZeroStr = TempStr.Left(TempStr.Len() - 2);
	ZeroStr.Append("0");
	List_SOverlay->AddSlot()
	[
		DrawLine.ToSharedRef()
	];
	List_SOverlay->AddSlot()[
		SNew(SHorizontalBox)
		+ SHorizontalBox::Slot().AutoWidth()
		[
			SNew(STextBlock_TextStyleLambda_List)
				 .Justification(ETextJustify::Right)
				 .Text(FText::FromString(TempStr))
				 .TEXTSTYLE("AlibabaRegular_12_83AAD6FF")
		]
		+ SHorizontalBox::Slot().FillWidth(1).Padding(FMargin(12, 0, 0, 0))
		[
			SAssignNew(ZhuScroll, Plugin_List::SCollisionScrollBox_List)
   			.Orientation(EOrientation::Orient_Horizontal)
   			.ScrollBarVisibility(EVisibility::Collapsed)
   			.OnUserScrolled_Lambda([this](float jindu)
			                                                            {
				                                                            float moveto = jindu / ZhuScroll->GetScrollOffsetOfEnd();
				                                                            Slider->SetValue(moveto);
				                                                            TextScroll->SetScrollOffset(jindu);
			                                                            })
			+ Plugin_List::SCollisionScrollBox_List::Slot()
			[
				Pillar.ToSharedRef()
			]
		]
	];

	//显示整个表格
	TSharedPtr<SVerticalBox> ShowList;
	SAssignNew(ShowList, SVerticalBox)
		+ SVerticalBox::Slot().FillHeight(1)
		[
			List_SOverlay.ToSharedRef()
		]
		+ SVerticalBox::Slot().AutoHeight()
		[
			SNew(SHorizontalBox)
			+ SHorizontalBox::Slot().AutoWidth().Padding(FMargin(0, -10, 0, 0))
			[
				SNew(STextBlock_TextStyleLambda_List)
         					 .Justification(ETextJustify::Right)
         					 .Text(FText::FromString(ZeroStr))
         					 .TEXTSTYLE("AlibabaRegular_12_83AAD6FF")
			]
			+ SHorizontalBox::Slot().FillWidth(1).Padding(FMargin(12, 0, 0, 0))
			[

				SNew(SVerticalBox)
				+ SVerticalBox::Slot().AutoHeight()
				[
					SNew(SBox).HeightOverride(1)
					[
						SNew(SColorBlock).Color(FLinearColor(0.27, 0.4, 0.67, 1.0))
					]
				]
				+ SVerticalBox::Slot().AutoHeight()
				[
					SAssignNew(Slider, SSlider)
					.Style(ListUIStyle::SliderStyle)
					.IndentHandle(false)
						.OnValueChanged_Lambda([this](float value)
					     {
						     float moveto = value * TextScroll->GetScrollOffsetOfEnd();
						     TextScroll->SetScrollOffset(moveto);
						     ZhuScroll->SetScrollOffset(moveto);
					     })
						.SliderBarColor(FLinearColor(1, 1, 1, 0))
						.Orientation(Orient_Horizontal)
						.MaxValue(1)
						.MinValue(0)
						.Value(0.0f)
				]
			]
		]
		+ SVerticalBox::Slot().AutoHeight()
		[
			SNew(SBox).HeightOverride(100)
			[
				SNew(SHorizontalBox)
				+ SHorizontalBox::Slot().AutoWidth().Padding(FMargin(0, -10, 12, 0))
				[
					SNew(STextBlock_TextStyleLambda_List)
					 .Justification(ETextJustify::Right)
					 .Text(FText::FromString(TempStr))
					 .TEXTSTYLE("AlibabaRegular_12_83AAD6FF")
				]
				+ SHorizontalBox::Slot().FillWidth(1)
				[
					SAssignNew(TextScroll, Plugin_List::SCollisionScrollBox_List)
			  		 .Orientation(EOrientation::Orient_Horizontal)
			  		 .ScrollBarVisibility(EVisibility::Collapsed)
			  		 .OnUserScrolled_Lambda([this](float jindu)
					                                                             {
						                                                             float moveto = jindu / ZhuScroll->GetScrollOffsetOfEnd();
						                                                             Slider->SetValue(moveto);
						                                                             ZhuScroll->SetScrollOffset(jindu);
					                                                             })
					+ Plugin_List::SCollisionScrollBox_List::Slot()
					[
						NameLise.ToSharedRef()
					]
				]
			]
		];

	ListContent->SetContent(ShowList.ToSharedRef());
}

void SOneList::UpDataTitleName(const FString InTitleName)
{
	TitleText->SetText(FText::FromString(InTitleName));
}

void SOneList::CleanList()
{
	UpDataList(BeforeWidth,TMap<FString, float>());
}
